﻿/*    file: main.cpp
 *    desc:
 * 
 * created: 2016-04-06
 *  author: chuanjiang.zh@qq.com
 * company: 
 */

#include <stdio.h>
#include <iostream>
#include <algorithm>

#include <assert.h>
#include <errno.h>
#include <memory>
#include <string>


#include "HCNetSDK.h"

#include "TStringUtil.h"
#include "TFileUtil.h"


class Application 
{
public:
	Application():
		m_user(-1),
		m_deviceInfo(),
		m_alarmHandle(-1)
	{
		NET_DVR_Init();
	}

	~Application()
	{
		NET_DVR_Cleanup();
	}
	
	bool login(const std::string& ip, int port, const std::string& user, const std::string& password)
	{
		//m_user = NET_DVR_Login_V30(const_cast<char*>(ip.c_str()), port,
		//	const_cast<char*>(user.c_str()), const_cast<char*>(password.c_str()), &m_deviceInfo);
		NET_DVR_USER_LOGIN_INFO loginInfo = NET_DVR_USER_LOGIN_INFO();
		strcpy(loginInfo.sDeviceAddress, ip.c_str());
		loginInfo.wPort = port;
		strcpy(loginInfo.sUserName, user.c_str());
		strcpy(loginInfo.sPassword, password.c_str());
		m_user = NET_DVR_Login_V40(&loginInfo, &m_deviceInfo40);
			
		return m_user >= 0;
	}

	void close()
	{
		if (m_alarmHandle >= 0)
		{
			NET_DVR_CloseAlarmChan_V30(m_alarmHandle);
			m_alarmHandle = -1;
		}

		NET_DVR_Logout(m_user);
	}

	static BOOL CALLBACK MSGCallBack_V31(LONG lCommand, NET_DVR_ALARMER *pAlarmer, char *pAlarmInfo, DWORD dwBufLen, void* pUser)
	{
		printf("MSGCallBack_V31. cmd: %d\n", lCommand);

		if (lCommand == COMM_ALARM_PDC)
		{
			NET_DVR_PDC_ALRAM_INFO alarmInfo = NET_DVR_PDC_ALRAM_INFO();
			memcpy(&alarmInfo, pAlarmInfo, sizeof(alarmInfo));

			printf("mode: %d, chl: %d, smart: %d, byBrokenNetHttp: %d, enter: %d, leav: %d, pass: %d\n",
				alarmInfo.byMode,
				alarmInfo.byChannel, alarmInfo.bySmart,
				alarmInfo.byBrokenNetHttp,
				alarmInfo.dwEnterNum, alarmInfo.dwLeaveNum, alarmInfo.dwPassingNum);

			if (alarmInfo.byMode == 0)
			{
				saveRss(alarmInfo.dwEnterNum, alarmInfo.dwLeaveNum);
			}
		}

		return TRUE;
	}

	static BOOL CALLBACK MessageCallBack(LONG lCommand, char *sDVRIP, char *pBuf, DWORD dwBufLen, DWORD dwUser)
	{
		printf("MessageCallBack. cmd: %d\n", lCommand);
		return TRUE;
	}

	static void CALLBACK RemoteConfigCallback(DWORD dwType, void* lpBuffer, DWORD dwBufLen, void* pUserData)
	{
		printf("RemoteConfigCallback. type: %d\n", dwType);
	}

	void test()
	{
		BOOL ret = NET_DVR_SetDVRMessageCallBack_V31(MSGCallBack_V31, this);
		printf("ret: %d\n", ret);

		//NET_DVR_SetDVRMessageCallBack(MessageCallBack, (DWORD)((void*)this));

		NET_DVR_SETUPALARM_PARAM alarmParam = { 0 };
		alarmParam.dwSize = sizeof(alarmParam);
		alarmParam.byAlarmInfoType = 0;
		m_alarmHandle = NET_DVR_SetupAlarmChan_V41(m_user, &alarmParam);

		//saveRss(0, 0);
		//testPdc();
		getPdcResult();
	}

#define ISAPI_STATUS_LEN      (4096*4)
#define ISAPI_DATA_LEN        (4096*4)

	void testPdc()
	{
		char statusBuffer[4096 * 4] = { 0 };
		LONG    m_lChannel = 0;

		NET_DVR_STD_CONFIG struCfg = { 0 };
		struCfg.lpCondBuffer = &m_lChannel;
		struCfg.dwCondSize = sizeof(m_lChannel);
		NET_DVR_PDC_RECOMMEND strPDCRecommend = { 0 };
		strPDCRecommend.dwSize = sizeof(strPDCRecommend);

		struCfg.lpOutBuffer = &strPDCRecommend;
		struCfg.dwOutSize = sizeof(strPDCRecommend);

		memset(statusBuffer, 0, ISAPI_STATUS_LEN);
		struCfg.lpStatusBuffer = statusBuffer;
		struCfg.dwStatusSize = ISAPI_STATUS_LEN;
		BOOL ret = NET_DVR_GetSTDConfig(m_user, NET_DVR_GET_PDC_RECOMMEND, &struCfg);
		printf("ret: %d\n", ret);
	}

	void getPdcResult()
	{
		NET_DVR_PDC_QUERY_COND cond = {0};
		cond.dwSize = sizeof(cond);
		cond.dwChannel = 0;

		cond.struStartTime.wYear = 2018;
		cond.struStartTime.byMonth = 9;
		cond.struStartTime.byDay = 1;
		cond.struStartTime.byHour = 0;
		cond.struStartTime.byMinute = 0;
		cond.struStartTime.bySecond = 0;

		cond.struEndTime.wYear = 2018;
		cond.struEndTime.byMonth = 9;
		cond.struEndTime.byDay = 2;
		cond.struEndTime.byHour = 0;
		cond.struEndTime.byMinute = 0;
		cond.struEndTime.bySecond = 0;

		cond.byReportType = 1;

		cond.byEnableProgramStatistics = true;
		cond.dwPlayScheduleNo = 0;
		cond.byTriggerPeopleCountingData = true;


		NET_DVR_PDC_RESULT result = NET_DVR_PDC_RESULT();
		result.dwSize = sizeof(result);

		LPVOID lpInBuffer = (LPVOID)NET_DVR_GET_PDC_RESULT;
		LONG handle = NET_DVR_StartRemoteConfig(m_user, NET_DVR_GET_PDC_RESULT,
			lpInBuffer, 4, RemoteConfigCallback, this);
		if (handle < 0)
		{
			DWORD err = NET_DVR_GetLastError();
			printf("err: %d. %s\n", err, NET_DVR_GetErrorMsg());
			return;
		}

		NET_DVR_GetNextRemoteConfig(handle, (void*)&result, sizeof(result));

		NET_DVR_StopRemoteConfig(handle);
	}

	static void saveRss(int enterNum, int leaveNum)
	{
		std::string text;
		text += "<?xml version=\"1.0\" encoding=\"gb2312\"?>";
		text += "<rss version=\"2.0\">";
		text += "<channel>";

		text += "<title></title>";
		text += "<description></description>";
		text += "<language>zh-cn</language>";
		text += "<generator></generator>";

		text += "<item>";
		text += comn::StringUtil::format("<title>进入: %d, 离开: %d</title>", enterNum, leaveNum);
		text += "</item>";

		text += "<item>";
		text += "</item>";

		text += "</channel>";
		text += "</rss>";

		comn::FileUtil::write(text.c_str(), text.size(), "d:\\website\\telerss.xml", false);
	}

	LONG	m_user;
	NET_DVR_DEVICEINFO_V30	m_deviceInfo;
	NET_DVR_DEVICEINFO_V40	m_deviceInfo40;

	LONG	m_alarmHandle;

};


int main(int argc, char** argv)
{
	Application app;

	//std::string ip = "192.168.3.65";
	std::string ip = "192.168.5.237";
	std::string user = "admin";
	//std::string password = "sjld16301";
	std::string password = "admin12345";

	if (!app.login(ip, 8000, user, password))
	{
		printf("failed to login.\n");
		return 0;
	}

	app.test();

	while (true)
	{
		std::cout << "$";
		
		std::string line;
		std::getline(std::cin, line);
		if (line == "q")
		{
			break;
		}
	}

	app.close();

	return 0;
}

